package org.llc.authorization.config.extend;

import org.llc.authorization.config.util.AuthProperties;
import org.springframework.security.oauth2.common.exceptions.OAuth2Exception;
import org.springframework.stereotype.Component;
import org.llc.authorization.service.UserAccountService;
import org.llc.common.starter.constants.Oauth2ExceptionEnum;
import org.llc.common.starter.model.UserAccount;

/**
 * 刷新token鉴权
 *
 * @author llc
 * @date 2020/2/28 11:58
 * @since 1.0.0
 */
@Component
public class RefreshTokenAuthenticator extends AbstractPrepareIntegrationAuthenticator  {

    /**
     * 刷新token
     */
    private final static String AUTH_TYPE = "refresh_token";

    /**
     * 用户账户Service
     */
    private final UserAccountService userAccountService;

    public RefreshTokenAuthenticator(UserAccountService userAccountService) {
        this.userAccountService = userAccountService;
    }

    /**
     * 刷新token时进行认证
     * <p>为获取Authentication 对象.</p>
     * @param entity 集成认证实体
     * @return org.llc.common.model.UserAccount
     * @author llc
     * @date 2020/2/28 16:02
     */
    @Override
    public UserAccount authenticate(IntegrationAuthenticationEntity entity) {
        // 获取用户名
        String username = entity.getAuthParameter(AuthProperties.USERNAME_PARAMETER_NAME);

        // 用户名为空
        if(username == null){
            throw new OAuth2Exception(Oauth2ExceptionEnum.USERNAME_NULL.getMsg());
        }
        // 根据用户名查询用户账户
        UserAccount userAccount = userAccountService.selectByUserName(username);
        if(null == userAccount){
            throw new OAuth2Exception(Oauth2ExceptionEnum.USER_NOT_FOUND.getMsg());
        }
        // 验证用户可用性
        userAccountService.validateUser(userAccount);

        // 组合用户账户对象与角色权限
        return userAccountService.composeUserAccountAndAuthority(userAccount);
    }

    /**
     * 刷新token方式
     * {@inheritDoc}
     * @author llc
     * @date 2020/2/28 16:46
     */
    @Override
    public boolean support(IntegrationAuthenticationEntity entity) {
        return AUTH_TYPE.equals(entity.getAuthType());
    }
}
